Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Implement support for Guest Users #4514

Merged
merged 5 commits into from
Mar 4, 2025
Merged

Conversation

Baalmart
Copy link
Contributor

@Baalmart Baalmart commented Mar 2, 2025

Description

This pull request introduces a dedicated GuestUser model and enhances guest user management.

Key features include:

  • Creation of guest user accounts with unique IDs.
  • Listing, retrieving, updating, and deleting of guest users.
  • Conversion of guest users to full accounts.
  • Improved validation and error handling for guest user-related operations.
  • Implementation of a new util, controller and model file for guest users.
  • New and modified endpoints.

These changes allow for a more scalable and flexible system for handling unauthenticated users, particularly in scenarios where guest users are numerous and long-lived.

Changes Made

  • Created GuestUser Model:
    • Defined the GuestUserSchema with fields for guest_id, lastActive and tenant.
    • Implemented the register static function.
    • Implemented the list static function.
    • Implemented the modify static function.
    • Implemented the remove static function.
  • Created guestUser.util.js:
    • Implemented create to create a guest user.
    • Implemented list to retrieve multiple guest users.
    • Implemented getOne to retrieve one guest user.
    • Implemented update to modify a guest user.
    • Implemented delete to remove a guest user.
    • Implemented convertGuest to convert a guest user to a full user.
  • Created guestUser.controller.js:
    • Implemented create to handle the creation of a guest user.
    • Implemented list to handle requests for multiple guest users.
    • Implemented getOne to handle request for one guest user.
    • Implemented update to handle requests to update guest users.
    • Implemented delete to handle requests for deletion of guest users.
    • Implemented convertGuest to handle the conversion of a guest user to a full user.
  • Created guestUser.routes.js:
    • Added POST /api/v2/users/guests to create a guest user.
    • Added GET /api/v2/users/guests to list guest users.
    • Added GET /api/v2/users/guests/:id to retrieve one guest user.
    • Added PUT /api/v2/users/guests/:id to update a guest user.
    • Added DELETE /api/v2/users/guests/:id to delete a guest user.
    • Added POST /api/v2/users/guests/convert to convert a guest to a user.
    • Added the correct authentication and authorization middleware.
  • Created guestUser.validators.js:
    • Implemented create validation for the POST /api/v2/users/guests/ route.
    • Implemented list validation for the GET /api/v2/users/guests/ route.
    • Implemented getOne validation for the GET /api/v2/users/guests/:id route.
    • Implemented update validation for the PUT /api/v2/users/guests/:id route.
    • Implemented delete validation for the DELETE /api/v2/users/guests/:id route.
    • Implemented convertGuest validation for the POST /api/v2/users/guests/convert route.
    • implemented the pagination middleware.
  • Updated generate-filter.js:
    • Added generateFilter.guest_users to create filters for GuestUser queries.
  • Modified user.util.js:
    • Add a new createGuest function.
    • Updated the convertGuest function.
  • Modified user.controller.js:
    • Add a new createGuest controller.
    • Updated the convertGuest controller.
  • Modified user.routes.js:
    • Updated the guest related routes.
  • Modified user.validators.js:
    • Update the validators.

Testing

  • Tested locally
  • Tested against staging environment
  • Relevant tests passed: [List test names]

Affected Services

  • Which services were modified:
    • Auth Service

Endpoints Ready for Testing

  • New endpoints ready for testing:

  • POST /api/v2/users/guests

    • Description: Create a new guest user.
    • Authentication: None
  • GET /api/v2/users/guests

    • Description: Retrieve a list of guest users.
    • Authentication: Required (JWT)
  • GET /api/v2/users/guests/:id

    • Description: Retrieve a specific guest user by ID.
    • Authentication: Required (JWT)
  • PUT /api/v2/users/guests/:id

    • Description: Update a guest user's information.
    • Authentication: Required (JWT)
  • DELETE /api/v2/users/guests/:id

    • Description: Delete a guest user.
    • Authentication: Required (JWT)
  • POST /api/v2/users/guests/convert

    • Description: Convert a guest user to a full user.
    • Authentication: Required (JWT)

API Documentation Updated?

  • Yes, API documentation was updated
  • No, API documentation does not need updating

Additional Notes

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Introduced comprehensive guest user management, including endpoints for creation, retrieval, update, deletion, listing, and conversion.
    • Added secure routes with JWT authentication and robust input validations, including pagination controls.
    • Implemented a new database schema for guest users with unique identifiers and activity tracking.
    • Enhanced error handling and response consistency for improved reliability.
    • Added CORS handling middleware for improved request management.
    • Introduced validation middleware for pagination and request validation to ensure data integrity.

Copy link
Contributor

coderabbitai bot commented Mar 2, 2025

📝 Walkthrough

Walkthrough

The changes introduce a comprehensive guest user management feature into the auth service. A new controller handles guest user operations (create, read, update, convert, list, delete) and leverages utility functions for processing and error management. A corresponding Mongoose model defines the guest user schema and registration logic. Additionally, new Express routes, filter generation logic, and validation middleware are implemented to support and secure these operations. The new routes are integrated into the API, ensuring consistent processing of guest user requests through proper error handling and response formatting.

Changes

File(s) Change Summary
src/auth-service/controllers/guest-user.controller.js Added new controller with asynchronous methods (create, getOne, convertGuest, list, update, delete) for guest user operations, including error extraction and tenant handling.
src/auth-service/models/GuestUser.js Introduced a new Mongoose schema for guest users with fields like guest_id and lastActive, a static register method, and tenant-specific model retrieval.
src/auth-service/routes/v2/guests.routes.js
src/auth-service/routes/v2/index.js
Added a new Express router for guest user endpoints with routes for creation, conversion, listing, updating, deletion, and retrieval; integrated into the main router.
src/auth-service/utils/guest-user.util.js Created a utility module encapsulating guest user operations that mirror the controller methods with consistent error handling practices.
src/auth-service/utils/common/generate-filter.js Augmented the filter object with a new method guest_users to construct dynamic query filters from request data.
src/auth-service/validators/guest-user.validators.js Developed new validation middleware including pagination, tenant, and parameter checks, exporting validation arrays for various guest user operations.
src/auth-service/validators/common/headers.validators.js Introduced a new middleware function headers to manage CORS by setting appropriate HTTP headers.
src/auth-service/validators/common/index.js Created an index file to export validation modules for centralized access.
src/auth-service/validators/common/pagination.validators.js Added a middleware function pagination to validate and set pagination parameters for incoming requests.
src/auth-service/validators/common/validate.validators.js Introduced a validation middleware function validate to handle request validation errors.

Suggested reviewers

  • BenjaminSsempala
  • Psalmz777

Poem

In lines of code, a guest is born,
Operations clear as a calm new morn.
With each function and route laid neat,
Errors handled, results complete.
Cheers to the code, both swift and bright!
🚀 Happy coding in the digital light!
Let guest users join the flight.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Mar 2, 2025

Codecov Report

Attention: Patch coverage is 0% with 11 lines in your changes missing coverage. Please review.

Project coverage is 11.51%. Comparing base (98474c7) to head (1378314).
Report is 11 commits behind head on staging.

Files with missing lines Patch % Lines
src/auth-service/utils/common/generate-filter.js 0.00% 11 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           staging    #4514      +/-   ##
===========================================
- Coverage    11.57%   11.51%   -0.07%     
===========================================
  Files          159      155       -4     
  Lines        18733    18709      -24     
  Branches       547      549       +2     
===========================================
- Hits          2169     2154      -15     
+ Misses       16560    16551       -9     
  Partials         4        4              
Files with missing lines Coverage Δ
src/auth-service/utils/common/generate-filter.js 2.06% <0.00%> (-0.05%) ⬇️

... and 4 files with indirect coverage changes

@Baalmart Baalmart changed the title Feat: Implement Full CRUD and Conversion for Guest Users Feat: Implement support for Guest Users Mar 2, 2025
Copy link
Contributor

github-actions bot commented Mar 2, 2025

Auth-service changes in this PR available for preview here

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (11)
src/auth-service/models/GuestUser.js (2)

36-51: Consider different response structure for failed creation.

The response when a guest user is not successfully created still has success: true, which could be misleading. Consider setting success: false for clarity.

      } else {
        return {
-          success: true,
+          success: false,
          data: createdGuestUser,
          message:
            "Operation successful but guest user NOT successfully created",
          status: httpStatus.OK,
        };
      }

64-74: Model retrieval logic can be simplified.

The current implementation tries to retrieve the model first and creates it if there's an error. A more direct approach would be to check if the model exists first using mongoose.modelNames().

const GuestUserModel = (tenant) => {
  const defaultTenant = constants.DEFAULT_TENANT || "airqo";
  const dbTenant = isEmpty(tenant) ? defaultTenant : tenant;
  try {
-    let users = mongoose.model("guest_users");
-    return users;
-  } catch (error) {
-    let users = getModelByTenant(dbTenant, "guest_user", GuestUserSchema);
-    return users;
+    const modelName = "guest_users";
+    return mongoose.modelNames().includes(modelName) 
+      ? mongoose.model(modelName)
+      : getModelByTenant(dbTenant, "guest_user", GuestUserSchema);
+  } catch (error) {
+    logger.error(`Error retrieving guest user model: ${error.message}`);
+    throw error;
  }
};
src/auth-service/routes/v2/guests.routes.js (1)

7-16: Consider using Express middleware for CORS.

Instead of implementing a custom CORS headers middleware, consider using the widely-adopted cors package which provides more comprehensive CORS handling and is better maintained.

const express = require("express");
const router = express.Router();
+const cors = require("cors");
const guestUserController = require("@controllers/guest-user.controller");
const guestUserValidations = require("@validators/guest-user.validators");
const { setJWTAuth, authJWT } = require("@middleware/passport");

-const headers = (req, res, next) => {
-  res.header("Access-Control-Allow-Origin", "*");
-  res.header(
-    "Access-Control-Allow-Headers",
-    "Origin, X-Requested-With, Content-Type, Accept, Authorization"
-  );
-  res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH");
-  next();
-};
-router.use(headers);
+router.use(cors({
+  origin: "*",
+  methods: ["GET", "POST", "PUT", "DELETE", "PATCH"],
+  allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"]
+}));
src/auth-service/utils/guest-user.util.js (4)

11-31: Potential duplication check for new guest users

Currently, the create function registers a new guest user without verifying if a user with the same email or data already exists. This could lead to duplicate guest accounts. Consider adding a check or letting the register method handle duplicates gracefully.


32-93: Incomplete data migration logic

The comment “migrate data from guest to new user” indicates there’s more data that should be transferred during guest conversion. If additional fields need to be moved, consider finalizing this logic to prevent data loss or inconsistencies.

Do you want assistance implementing the data migration logic?


141-162: Guest deletion appears straightforward

Consider auditing any related records or data (e.g., logs, references in other tables/collections) if a guest user is removed.


163-196: Return 404 instead of 200 when not found

Currently, the code returns a success status even if the guest user doesn’t exist. To align with REST best practices, consider returning an HTTP 404 status for not found results.

src/auth-service/validators/guest-user.validators.js (2)

19-37: Validate tenant values

Hardcoding tenant values is fine for a small set, but if additional tenants are expected, consider dynamically loading from configuration. Also, verify that "airqount" is the intended string.


64-84: Additional validations for email or password

Consider adding stricter rules for email format (.isEmail()) and password complexity (e.g., .isLength({ min: 8 })).

src/auth-service/controllers/guest-user.controller.js (2)

17-67: Repeated pre-processing logic

Checking for request errors, setting a default tenant, and calling the utility is repeated in every method. Consider extracting this logic into a shared helper to reduce duplication.


168-217: Pagination clarity

When listing guest users, consider including pagination info (like totalCount, skip, limit) in the response to make it more user-friendly.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7179ab2 and 95b23e7.

📒 Files selected for processing (7)
  • src/auth-service/controllers/guest-user.controller.js (1 hunks)
  • src/auth-service/models/GuestUser.js (1 hunks)
  • src/auth-service/routes/v2/guests.routes.js (1 hunks)
  • src/auth-service/routes/v2/index.js (1 hunks)
  • src/auth-service/utils/common/generate-filter.js (1 hunks)
  • src/auth-service/utils/guest-user.util.js (1 hunks)
  • src/auth-service/validators/guest-user.validators.js (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-push-deploy-auth-service
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (16)
src/auth-service/routes/v2/index.js (1)

30-30: Integration of guest users route looks good.

The new route for guest users is properly integrated into the existing router structure. The placement before the catch-all users route ("/") is appropriate, as more specific routes should come before general ones.

src/auth-service/utils/common/generate-filter.js (1)

99-127: Well-structured filter implementation for guest users.

The implementation follows the established pattern in the codebase for filter generation. The conversion of tenant to lowercase ensures consistent filtering regardless of input case, and the proper handling of MongoDB ObjectId for the id field is correct.

src/auth-service/models/GuestUser.js (1)

12-23: Schema design is appropriate for guest user requirements.

The schema includes essential fields with proper indexing. Using timestamps: true is a good practice for tracking creation and update times automatically.

src/auth-service/routes/v2/guests.routes.js (3)

21-27: List endpoint properly secured with authentication.

The guest user listing endpoint is appropriately secured with JWT authentication middleware, ensuring that only authenticated users can access this potentially sensitive data.


28-48: Consistent authentication pattern for modification endpoints.

The update, delete, and getOne endpoints all follow a consistent pattern of validation followed by authentication, which is good practice for security and maintainability.


19-20:

❓ Verification inconclusive

Creating guest users doesn't require authentication.

The POST route for creating guest users doesn't require authentication, which is appropriate for enabling unauthenticated users to start using the system. However, make sure this aligns with your security requirements.


🏁 Script executed:

#!/bin/bash
# Check if there are any security validations in the guest user creation controller

grep -n "require\(\|verif\|check\|guard\|secure\|valid" src/auth-service/controllers/guest-user.controller.js | grep -i "create\|guest"

Length of output: 161


I'll re-run the search for security validations using a corrected regex so we can verify whether any checks exist in the guest user creation controller. Please run the following script:

Based on the intended design, creating guest users is supposed to be unauthenticated. If this updated check returns no output, it confirms that there are no hidden security validations—for now—which aligns with the design. Still, please verify manually that this behavior meets your overall security requirements.


Guest User Creation Endpoint – Unauthenticated by Design

The guest user creation route (using router.post("/", guestUserValidations.create, guestUserController.create)) is deliberately left open to allow unauthenticated users to start using the system. No extra security validations were found in the controller for guest creation, so this behavior appears intentional. Please ensure that this design decision fits your security requirements, knowing that the conversion endpoint remains protected.


🏁 Script executed:

[run_scripts]
#!/bin/bash
# Re-run the check for any security validations in the guest-user.controller.js file
grep -En "require\(|verif|check|guard|secure|valid" src/auth-service/controllers/guest-user.controller.js | grep -Ei "create|guest"

Length of output: 314


Guest User Creation Endpoint – Unauthenticated by Design (Re-verified)

The updated check in the guest user controller only revealed the import of the guest user utility:

  • const guestUserUtil = require("@utils/guest-user.util");

No additional security validations or authentication checks were detected. This confirms that the unauthenticated guest user creation route defined in:

router.post("/", guestUserValidations.create, guestUserController.create);
router.post("/convert", setJWTAuth, authJWT, guestUserController.convertGuest);

is intentional for allowing unauthenticated users to initiate use of the system. Please ensure that this design decision is in line with your overall security requirements, keeping in mind that the conversion endpoint remains protected.

src/auth-service/utils/guest-user.util.js (3)

1-9: Imports look consistent

The chosen modules appear relevant and well-organized.


94-116: Filtering approach is solid

The function effectively uses generateFilter.guest_users(), skip, and limit. This is a standard approach for paginated listing.


117-140: Update logic

The function merges body into an update object but doesn't apply any transformations or validations beyond what's in the validators. Ensure that fields like guest_id or other unique fields are not changed inadvertently if that violates your data model.

src/auth-service/validators/guest-user.validators.js (2)

5-17: Pagination defaults look good

The logic ensures valid numeric values for limit and skip, with sensible defaults and upper bounds.


39-54: Robust ID parameter validation

Ensuring it’s a valid MongoDB ObjectId is helpful. This helps avoid cast errors in queries.

src/auth-service/controllers/guest-user.controller.js (5)

1-16: Structured imports

The controller’s imports are well-organized and relevant.


68-117: Consistent approach for retrieval

The logic for getOne is straightforward and consistent with the rest of the controller.


118-167: Verify error coverage

Ensure that any potential errors from the underlying convertGuest utility are appropriately handled. For instance, if data migration fails or if the user already exists, confirm that the utility sets result.success to false so this block can handle it gracefully.


219-268: Update method logic

Implementation is consistent with other endpoints, and error handling is robust.


269-319: Deletion flow is consistent

Error handling and success response structure is consistent with the overall pattern.

Comment on lines 25 to 63
async register(args, next) {
try {
const guestId = accessCodeGenerator
.generate(constants.RANDOM_PASSWORD_CONFIGURATION(16))
.toUpperCase();

const createdGuestUser = await this.create({
guest_id: guestId,
...args,
});

if (!isEmpty(createdGuestUser)) {
return {
success: true,
data: createdGuestUser,
message: "guest user created",
status: httpStatus.OK,
};
} else {
return {
success: true,
data: createdGuestUser,
message:
"Operation successful but guest user NOT successfully created",
status: httpStatus.OK,
};
}
} catch (err) {
logger.error(`🐛🐛 Internal Server Error -- ${err.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: err.message }
)
);
}
},
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing import for isEmpty function in register method.

The register method uses isEmpty() at line 36, but there's no import for this function in the file.

Add the following import at the top of the file:

const httpStatus = require("http-status");
+const isEmpty = require("is-empty");
const { logObject, logText, HttpError } = require("@utils/shared");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async register(args, next) {
try {
const guestId = accessCodeGenerator
.generate(constants.RANDOM_PASSWORD_CONFIGURATION(16))
.toUpperCase();
const createdGuestUser = await this.create({
guest_id: guestId,
...args,
});
if (!isEmpty(createdGuestUser)) {
return {
success: true,
data: createdGuestUser,
message: "guest user created",
status: httpStatus.OK,
};
} else {
return {
success: true,
data: createdGuestUser,
message:
"Operation successful but guest user NOT successfully created",
status: httpStatus.OK,
};
}
} catch (err) {
logger.error(`🐛🐛 Internal Server Error -- ${err.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: err.message }
)
);
}
},
};
// File: src/auth-service/models/GuestUser.js
const httpStatus = require("http-status");
const isEmpty = require("is-empty");
const { logObject, logText, HttpError } = require("@utils/shared");
// ... other imports and code ...
async register(args, next) {
try {
const guestId = accessCodeGenerator
.generate(constants.RANDOM_PASSWORD_CONFIGURATION(16))
.toUpperCase();
const createdGuestUser = await this.create({
guest_id: guestId,
...args,
});
if (!isEmpty(createdGuestUser)) {
return {
success: true,
data: createdGuestUser,
message: "guest user created",
status: httpStatus.OK,
};
} else {
return {
success: true,
data: createdGuestUser,
message:
"Operation successful but guest user NOT successfully created",
status: httpStatus.OK,
};
}
} catch (err) {
logger.error(`🐛🐛 Internal Server Error -- ${err.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: err.message }
)
);
}
},

Copy link
Contributor

github-actions bot commented Mar 2, 2025

Auth-service changes in this PR available for preview here

@Baalmart Baalmart marked this pull request as draft March 2, 2025 17:04
@Baalmart Baalmart marked this pull request as ready for review March 3, 2025 18:18
Copy link
Contributor

github-actions bot commented Mar 3, 2025

Auth-service changes in this PR available for preview here

@Baalmart Baalmart marked this pull request as draft March 3, 2025 18:47
@Baalmart Baalmart marked this pull request as ready for review March 4, 2025 04:45
Copy link
Contributor

github-actions bot commented Mar 4, 2025

Auth-service changes in this PR available for preview here

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (12)
src/auth-service/utils/common/generate-filter.js (1)

101-105: Consider extracting additional filter parameters.

Most other filter methods in this file extract multiple parameters from requests, but this implementation only uses id and guest_id. Depending on the GuestUser schema and query requirements, you might need additional filters like tenant, which appears in other filter methods.

-      let { id, guest_id } = {
+      let { id, guest_id, tenant, lastActive } = {
         ...req.body,
         ...req.query,
         ...req.params,
       };
src/auth-service/validators/common/validate.validators.js (1)

7-10: Consider adding request identifiers for better error traceability.

For enhanced monitoring and debugging capabilities, consider adding a unique request identifier in the error object. This would help trace validation failures across logs and systems.

return next(
-  new HttpError("Validation Error", httpStatus.BAD_REQUEST, errors)
+  new HttpError("Validation Error", httpStatus.BAD_REQUEST, errors, req.id || undefined)
); // next with HttpError

You would need to modify your HttpError class to accept and store this identifier if it doesn't already.

src/auth-service/validators/common/headers.validators.js (3)

1-5: Commented code should be removed or properly documented.

There's a substantial amount of commented code at the beginning of this file that appears to be an alternate implementation using configurable allowed origins. Either remove this code entirely or add a comment explaining why it's preserved for future reference.

-// const constants = require("@config/constants");
-// const allowedOrigins =
-//   constants.ALLOWED_ORIGINS && constants.ALLOWED_ORIGINS.trim() !== ""
-//     ? constants.ALLOWED_ORIGINS.split(",").map((origin) => origin.trim())
-//     : ["*"];
+/* 
+ * Note: This more restrictive CORS implementation was preserved for future use
+ * when we need to limit allowed origins based on environment configuration.
+ * 
+ * const constants = require("@config/constants");
+ * const allowedOrigins =
+ *   constants.ALLOWED_ORIGINS && constants.ALLOWED_ORIGINS.trim() !== ""
+ *     ? constants.ALLOWED_ORIGINS.split(",").map((origin) => origin.trim())
+ *     : ["*"];
+ */

8-16: Remove or document these commented sections for clarity.

Similar to the previous comment, there's more commented code that should either be removed or properly documented with an explanation for why it's being preserved.

-// const origin = req.get("Origin");
-// res.setHeader(
-//   "Access-Control-Allow-Origin",
-//   allowedOrigins.includes("*")
-//     ? "*"
-//     : allowedOrigins.includes(origin)
-//     ? origin
-//     : ""
-// );
+/* 
+ * This is the implementation that would work with the configurable allowed origins.
+ * It would set the Access-Control-Allow-Origin header based on the requesting origin.
+ */

17-23: Consider security implications of allowing all origins.

Using "*" for Access-Control-Allow-Origin allows requests from any origin, which may present security risks in a production environment. Consider implementing a more restrictive CORS policy that only allows specific, trusted origins.

You could implement a more secure approach by using an environment-specific configuration:

-res.setHeader("Access-Control-Allow-Origin", "*");
+const allowedOrigins = process.env.ALLOWED_ORIGINS 
+  ? process.env.ALLOWED_ORIGINS.split(',').map(origin => origin.trim()) 
+  : [];
+const origin = req.get('Origin');
+
+if (process.env.NODE_ENV === 'development' || allowedOrigins.includes('*')) {
+  res.setHeader("Access-Control-Allow-Origin", "*");
+} else if (origin && allowedOrigins.includes(origin)) {
+  res.setHeader("Access-Control-Allow-Origin", origin);
+}

This approach would maintain the convenience of "*" in development but enforce a stricter policy in production.

src/auth-service/validators/common/pagination.validators.js (2)

15-16: Clarify the comment about skip assignment.

The comment "Assign 0 directly to skip. No need for req.query" is slightly confusing since req.query.skip is still assigned later. Consider clarifying or removing this comment.

if (Number.isNaN(skip) || skip < 0) {
-  skip = 0; // Assign 0 directly to skip. No need for req.query
+  skip = 0; // Reset to 0 for invalid values
}

8-13: Consider adding a response header for actual limits applied.

To improve API transparency, consider adding response headers that indicate the actual limit and maximum limit values applied to the request. This helps clients understand pagination constraints and adapt accordingly.

if (Number.isNaN(limit) || limit < 1) {
  limit = defaultLimit;
}
if (limit > maxLimit) {
  limit = maxLimit;
}
+
+// Set headers to inform client about applied limits
+res.setHeader('X-Pagination-Limit', limit);
+res.setHeader('X-Pagination-Max-Limit', maxLimit);
src/auth-service/routes/v2/guests.routes.js (2)

18-18: Clarify the use of global pagination middleware.

The route is using guestUserValidations.pagination globally for all routes, but pagination typically only applies to list operations. Consider moving this middleware to only apply to the relevant GET routes.

-router.use(guestUserValidations.pagination);
+// Only apply pagination middleware to the list endpoint
+router.get(
+  "/",
+  guestUserValidations.pagination,
+  guestUserValidations.list,
+  setJWTAuth,
+  authJWT,
+  validate,
+  guestUserController.list
+);

This assumes you would then remove the pagination middleware from the existing GET route or adjust its implementation accordingly.


26-32: Add documentation for guest conversion process.

The /convert endpoint is crucial but lacks documentation about what happens during conversion. Consider adding JSDoc or similar documentation to explain the conversion process, required parameters, and expected outcomes.

+/**
+ * @route POST /v2/guests/convert
+ * @description Converts a guest user to a full user account
+ * @access Private - Requires authentication
+ * @body {string} guest_id - ID of the guest user to convert
+ * @body {object} userData - User data for the new account
+ * @returns {object} The newly created full user account
+ */
router.post(
  "/convert",
  setJWTAuth,
  authJWT,
  validate,
  guestUserController.convertGuest
);
src/auth-service/models/GuestUser.js (3)

1-24: Be mindful of logging details in production.

Mongoose debug mode can increase verbosity and potentially reveal sensitive info. Ensure it's disabled or carefully managed in production to prevent exposing sensitive data in logs.


26-63: Clarify handling of 'empty' creation result.

this.create(...) typically returns a valid document or throws an error, making the “empty” check less likely. Consider treating an empty result as an error or refining the logic for better clarity.


224-224: Add unit tests for the static methods.

Testing the registration, listing, modification, removal, and counting of guest users ensures reliability over time.

Would you like assistance creating a new test file to provide coverage for these methods?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbd1c75 and d199e53.

📒 Files selected for processing (8)
  • src/auth-service/models/GuestUser.js (1 hunks)
  • src/auth-service/routes/v2/guests.routes.js (1 hunks)
  • src/auth-service/utils/common/generate-filter.js (1 hunks)
  • src/auth-service/validators/common/headers.validators.js (1 hunks)
  • src/auth-service/validators/common/index.js (1 hunks)
  • src/auth-service/validators/common/pagination.validators.js (1 hunks)
  • src/auth-service/validators/common/validate.validators.js (1 hunks)
  • src/auth-service/validators/guest-user.validators.js (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/auth-service/validators/common/index.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/auth-service/validators/guest-user.validators.js
🧰 Additional context used
🪛 GitHub Check: codecov/patch
src/auth-service/utils/common/generate-filter.js

[warning] 99-101: src/auth-service/utils/common/generate-filter.js#L99-L101
Added lines #L99 - L101 were not covered by tests


[warning] 106-106: src/auth-service/utils/common/generate-filter.js#L106
Added line #L106 was not covered by tests


[warning] 108-108: src/auth-service/utils/common/generate-filter.js#L108
Added line #L108 was not covered by tests


[warning] 111-111: src/auth-service/utils/common/generate-filter.js#L111
Added line #L111 was not covered by tests


[warning] 114-114: src/auth-service/utils/common/generate-filter.js#L114
Added line #L114 was not covered by tests


[warning] 116-117: src/auth-service/utils/common/generate-filter.js#L116-L117
Added lines #L116 - L117 were not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-push-deploy-auth-service
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (11)
src/auth-service/utils/common/generate-filter.js (2)

116-124: Error handling implementation is consistent with other methods.

The error handling approach mirrors that of other methods in this file, which is good for consistency. The logging and error forwarding with appropriate HTTP status codes will help with debugging and proper client notifications.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 116-117: src/auth-service/utils/common/generate-filter.js#L116-L117
Added lines #L116 - L117 were not covered by tests


107-112:

✅ Verification successful

Keep filter field population consistent with the GuestUser schema.

The implementation appropriately converts id to ObjectId but keeps guest_id as a string. Ensure this matches the schema definition of the GuestUser model for proper query functionality.


🏁 Script executed:

#!/bin/bash
# Find the GuestUser model schema to confirm field types

echo "Searching for GuestUser model definition..."
rg -A 10 "const GuestUserSchema = new (mongoose\.Schema|Schema)\(" --type js

echo "Checking for guest_id field usage in other files..."
rg "guest_id" --type js

Length of output: 1898


GuestUser Schema Consistency Verified
The GuestUser schema defines guest_id as a string (as shown in src/auth-service/models/GuestUser.js), and the filter in generate-filter.js is correctly setting guest_id without a conversion. The implementation is consistent with the schema, so no changes are necessary.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 108-108: src/auth-service/utils/common/generate-filter.js#L108
Added line #L108 was not covered by tests


[warning] 111-111: src/auth-service/utils/common/generate-filter.js#L111
Added line #L111 was not covered by tests

src/auth-service/validators/common/validate.validators.js (1)

1-14: Well-designed validation middleware with clear error handling.

This is a well-crafted validation middleware function that follows established patterns. The implementation properly extracts errors from requests, checks their existence, and either passes the errors as an appropriately formatted HTTP error or proceeds to the next middleware in the stack. The structure is clean and the error response includes all necessary components (message, status code, and detailed errors).

src/auth-service/validators/common/pagination.validators.js (1)

1-23: Well-implemented pagination middleware with proper validation.

This pagination middleware provides a robust approach to sanitizing and constraining pagination parameters. The implementation includes appropriate type checking, range validation, and sensible defaults. The middleware correctly applies only to GET requests with pagination parameters, ensuring it doesn't interfere with other request types.

src/auth-service/routes/v2/guests.routes.js (2)

41-64: Consistent authentication and validation flow across endpoints.

The route definitions for update, delete, and getOne operations follow a consistent pattern of validation, authentication, and controller invocation. This is a good practice for maintaining predictable API behavior and security.


28-32:

❓ Verification inconclusive

Ensure proper user identification during guest conversion.

For the /convert endpoint that converts a guest user to a full user, verify that you're properly identifying which guest account belongs to the authenticated user. This prevents unauthorized conversions of other users' guest accounts.


🏁 Script executed:

#!/bin/bash
# Check how guest user ownership is verified during conversion
# Search for the implementation of convertGuest to see how it validates ownership

echo "Examining guest user conversion implementation:"
rg -A 10 "convertGuest" --glob "src/auth-service/controllers/**"

Length of output: 2079


Clarification on Guest Account Validation

Before merging, please confirm that the conversion logic within guestUserUtil.convertGuest robustly verifies that the authenticated user is indeed the owner of the guest account being converted. The controller in src/auth-service/controllers/guest-user.controller.js delegates the conversion without an explicit verification check in the snippet—verify that the utility method correctly compares the authenticated user context against the guest account to prevent unauthorized conversions. If this check isn’t sufficiently enforced, consider adding explicit validation and corresponding test cases.

src/auth-service/models/GuestUser.js (5)

64-92: Listing logic looks solid.

This method correctly handles empty results and logs essential information.


103-132: Update logic is straightforward.

The function uses findOneAndUpdate with { new: true } to return the updated doc and properly handles the not-found scenario.


133-161: Removal logic is consistent.

Using findOneAndRemove is appropriate here, and the response states when the document is not found.


162-181: Count logic is properly implemented.

The method cleanly returns the total number of matching guest users.


182-210: findOne method is well-structured.

It returns a 404 status when not found and a 200 status otherwise, matching standard REST conventions.

Comment on lines +99 to +125
guest_users: (req, next) => {
try {
let { id, guest_id } = {
...req.body,
...req.query,
...req.params,
};
let filter = {};
if (id) {
filter["_id"] = ObjectId(id);
}
if (guest_id) {
filter["guest_id"] = guest_id;
}

return filter;
} catch (error) {
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
next(
new HttpError(
"Internal Server Error",
httpStatus.INTERNAL_SERVER_ERROR,
{ message: error.message }
)
);
}
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

The guest_users filter implementation looks good, but lacks test coverage.

The implementation follows the established pattern of other filter methods in this file by extracting relevant parameters from the request and constructing a filter object. However, the static analysis indicates that this new code lacks test coverage, which is crucial for authentication-related functionality.


🏁 Script executed:

#!/bin/bash
# Check for test files that might cover this new guest_users filter functionality

echo "Searching for test files related to guest user functionality..."
fd -e js -e ts test guest.*filter

echo "Searching for any imports or usages of the guest_users filter function..."
rg "filter.guest_users" --type js

Length of output: 466


Guest Users Filter: Add Test Coverage
The implementation of the guest_users filter is consistent with our established patterns, but our verification indicates that there are no tests covering this functionality. Given its importance in authentication, please add unit tests to ensure robust behavior and proper error handling.

  • File: src/auth-service/utils/common/generate-filter.js (lines 99–125)
  • Action: Add appropriate test cases for the guest_users filter to verify both successful filter construction and error handling.
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 99-101: src/auth-service/utils/common/generate-filter.js#L99-L101
Added lines #L99 - L101 were not covered by tests


[warning] 106-106: src/auth-service/utils/common/generate-filter.js#L106
Added line #L106 was not covered by tests


[warning] 108-108: src/auth-service/utils/common/generate-filter.js#L108
Added line #L108 was not covered by tests


[warning] 111-111: src/auth-service/utils/common/generate-filter.js#L111
Added line #L111 was not covered by tests


[warning] 114-114: src/auth-service/utils/common/generate-filter.js#L114
Added line #L114 was not covered by tests


[warning] 116-117: src/auth-service/utils/common/generate-filter.js#L116-L117
Added lines #L116 - L117 were not covered by tests

Comment on lines 8 to 17
const headers = (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH");
next();
};
router.use(headers);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid duplicating CORS middleware.

You've defined an inline CORS headers middleware here, but there also appears to be a standalone headers.validators.js file with similar functionality. To maintain DRY principles and ensure consistent header application across routes, import and use the shared middleware instead.

-const headers = (req, res, next) => {
-  res.header("Access-Control-Allow-Origin", "*");
-  res.header(
-    "Access-Control-Allow-Headers",
-    "Origin, X-Requested-With, Content-Type, Accept, Authorization"
-  );
-  res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH");
-  next();
-};
-router.use(headers);
+const { headers } = require("@validators/common");
+router.use(headers);

This assumes you've added the headers middleware to the exports in @validators/common/index.js.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const headers = (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH");
next();
};
router.use(headers);
const { headers } = require("@validators/common");
router.use(headers);

Comment on lines +34 to +40
"/",
guestUserValidations.list,
setJWTAuth,
authJWT,
validate,
guestUserController.list
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Restrict guest user listing based on permissions.

The list endpoint allows fetching all guest users, but this should likely be restricted based on the authenticated user's permissions or tenant. Ensure the controller implements appropriate filtering based on the user's role and tenant.


🏁 Script executed:

#!/bin/bash
# Check how guest user listing is filtered
# Search for the implementation of list to see how it filters results

echo "Examining guest user listing implementation:"
rg -A 10 "list.*guest" --glob "src/auth-service/controllers/**"

echo "Checking if tenant filtering is applied:"
rg -A 3 "tenant" --glob "src/auth-service/controllers/guest-user.controller.js"

Length of output: 3334


Action: Enhance Access Control for Guest User Listing

While tenant-based filtering is implemented in the guest user controller, there is no evidence of role-based permission checks. In addition to the tenant filter, please ensure that the guest user listing endpoint enforces restrictions based on the authenticated user's permissions or roles to prevent unauthorized access.

Recommendations:

  • Confirm that role-based access control is applied either in the controller or via dedicated middleware.
  • Consider adding explicit permission checks before invoking guestUserUtil.list.

Comment on lines +20 to +25
router.post(
"/",
guestUserValidations.create,
validate,
guestUserController.create
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Guest creation endpoint should validate tenant permissions.

The guest creation endpoint doesn't appear to have authentication middleware (setJWTAuth and authJWT), unlike the other endpoints. If this is intentional to allow unauthenticated guest creation, consider adding validation to prevent abuse, such as rate limiting or tenant verification.


🌐 Web query:

Are there any best practices for handling unauthenticated user registration with rate limiting?

💡 Result:

To handle unauthenticated user registration securely while preventing abuse, implement the following best practices combining rate limiting and security measures:

Rate Limiting Strategies

  • IP-based limits: Restrict unauthenticated registration attempts per IP. GitLab recommends starting with 3,600 requests/hour per IP, adjustable based on traffic[2].
  • Layered rules:
    • Allow 4 requests/minute with a Managed Challenge (CAPTCHA) for initial blocks[3].
    • Escalate to 10 requests/10 minutes for repeated violations[3].
    • Block IPs exceeding 20 requests/hour for 24 hours[3].
  • Response headers: Use headers like Retry-After and RateLimit-Reset to inform clients when to retry[2][8].

Security Enhancements

  • Avoid anonymous auth for attestation: Use AppCheck or similar tools instead of relying on anonymous tokens for app validation[1].
  • Managed Challenges: Trigger CAPTCHA or proof-of-work challenges after rate limits to deter bots[3].
  • Cleanup anonymous data: Automatically delete inactive anonymous accounts to reduce attack surfaces[1].

Registration Flow Design

  • Simplify forms: Collect minimal data upfront and use multi-step flows for additional details[4].
  • Offer social/enterprise logins: Reduce friction with OAuth or SAML integrations while shifting authentication burden to trusted providers[4].
  • Passwordless options: Enable email/magic link signups to avoid password-related risks[4].

Monitoring and Adjustments

  • Track headers: Monitor RateLimit-Observed and RateLimit-Remaining to detect abuse patterns[2].
  • Temporary limit increases: For bulk operations, request short-term exceptions with clear justification (Okta’s process)[9].

For high-traffic systems, combine these with global rate limits (e.g., 100 requests/second across all endpoints as in Auth0[6]) and ensure backend rules block anonymous users from privileged actions[1].

Citations:


Action Required: Enhance Security on Guest Creation Endpoint

The guest creation endpoint (located at src/auth-service/routes/v2/guests.routes.js, lines 20–25) currently lacks tenant permission validation and does not include the authentication middlewares (setJWTAuth and authJWT) found in other endpoints. If allowing unauthenticated guest registration is intentional, please ensure that you mitigate potential abuse by:

  • Implementing Rate Limiting: Apply IP-based limits (e.g., 3,600 requests/hour per IP), and consider layered strategies such as allowing a few requests per minute before escalating to CAPTCHA or temporary blocks. This helps manage request volume and discourages automated abuse.
  • Adding Tenant Verification: Validate tenant details during guest creation to ensure that only authorized tenants can register.
  • Consider Managed Challenges: Introducing mechanisms like CAPTCHA for repeated attempts can add an extra layer of security.

These adjustments align with industry best practices for handling unauthenticated user registration while protecting against abuse.

Comment on lines +212 to +222
const GuestUserModel = (tenant) => {
const defaultTenant = constants.DEFAULT_TENANT || "airqo";
const dbTenant = isEmpty(tenant) ? defaultTenant : tenant;
try {
let users = mongoose.model("guest_users");
return users;
} catch (error) {
let users = getModelByTenant(dbTenant, "guest_user", GuestUserSchema);
return users;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Unify the model name to maintain consistency.

Currently, the code tries mongoose.model("guest_users"), then creates a new model named "guest_user". This mismatch can cause confusion or lead to missing model references. Consider using the same name for both.

Here's a potential fix:

-    let users = getModelByTenant(dbTenant, "guest_user", GuestUserSchema);
+    let users = getModelByTenant(dbTenant, "guest_users", GuestUserSchema);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const GuestUserModel = (tenant) => {
const defaultTenant = constants.DEFAULT_TENANT || "airqo";
const dbTenant = isEmpty(tenant) ? defaultTenant : tenant;
try {
let users = mongoose.model("guest_users");
return users;
} catch (error) {
let users = getModelByTenant(dbTenant, "guest_user", GuestUserSchema);
return users;
}
};
const GuestUserModel = (tenant) => {
const defaultTenant = constants.DEFAULT_TENANT || "airqo";
const dbTenant = isEmpty(tenant) ? defaultTenant : tenant;
try {
let users = mongoose.model("guest_users");
return users;
} catch (error) {
let users = getModelByTenant(dbTenant, "guest_users", GuestUserSchema);
return users;
}
};

Copy link
Contributor

github-actions bot commented Mar 4, 2025

Auth-service changes in this PR available for preview here

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/auth-service/models/GuestUser.js (3)

33-71: Consider improving success response logic in register method

In the register method, I notice an inconsistency in the response structure. When a guest user is successfully created (lines 45-52), you return a success response with the created data, which is perfect. However, in the else block (lines 53-59), you still return success: true even though the message indicates that the guest user was NOT successfully created.

This inconsistency could confuse API consumers who might rely on the success flag to determine if the operation succeeded.

    } else {
      return {
-        success: true,
+        success: false,
        data: createdGuestUser,
        message:
          "Operation successful but guest user NOT successfully created",
        status: httpStatus.OK,
      };
    }

186-214: Rename custom findOne method to avoid shadowing Mongoose's native method

The static method named findOne potentially shadows Mongoose's built-in findOne method. While your implementation works correctly, this naming overlap could confuse developers familiar with Mongoose's API and lead to unexpected behavior if someone attempts to use the native method directly.

-async findOne({ filter = {}, next } = {}) {
+async getOneGuestUser({ filter = {}, next } = {}) {
  try {
    const guestUser = await this.findOne(filter).exec();

    if (!isEmpty(guestUser)) {
      return {
        success: true,
        data: guestUser,
        message: "successfully retrieved the guest user",
        status: httpStatus.OK,
      };
    } else {
      return {
        success: false,
        message: "guest user not found",
        status: httpStatus.NOT_FOUND,
      };
    }
  } catch (err) {
    logger.error(`🐛🐛 Internal Server Error -- ${err.message}`);
    next(
      new HttpError(
        "Internal Server Error",
        httpStatus.INTERNAL_SERVER_ERROR,
        { message: err.message }
      )
    );
  }
},

72-106: Consistent error handling and response formatting across methods

Great job implementing consistent error handling and response formatting across all the static methods. Each method properly handles errors, logs them using the logger, and returns well-structured responses. This consistency makes the API more predictable and easier to work with.

However, consider extracting the error handling logic into a helper function since it's repeated in each method. This would make the code more DRY and easier to maintain.

Here's a suggestion for a helper function that could be defined above the schema:

const handleModelError = (err, next) => {
  logger.error(`🐛🐛 Internal Server Error -- ${err.message}`);
  next(
    new HttpError(
      "Internal Server Error",
      httpStatus.INTERNAL_SERVER_ERROR,
      { message: err.message }
    )
  );
};

Then in each method, you could simplify the catch blocks:

  } catch (err) {
-    logger.error(`🐛🐛 Internal Server Error -- ${err.message}`);
-    next(
-      new HttpError(
-        "Internal Server Error",
-        httpStatus.INTERNAL_SERVER_ERROR,
-        { message: err.message }
-      )
-    );
+    handleModelError(err, next);
  }

Also applies to: 107-136, 137-165, 166-185

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d199e53 and 1378314.

📒 Files selected for processing (2)
  • src/auth-service/models/GuestUser.js (1 hunks)
  • src/auth-service/routes/v2/guests.routes.js (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-push-deploy-auth-service
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (8)
src/auth-service/models/GuestUser.js (3)

7-7: Kudos for including the 'isEmpty' import

Great job including the isEmpty utility that's used throughout the code. This demonstrates good attention to detail and ensures all dependencies are properly imported.


216-226: Unify the model name to maintain consistency

Currently, the code tries mongoose.model("guest_users"), then creates a new model named "guest_user". This mismatch can cause confusion or lead to missing model references. Consider using the same name for both.

-    let users = getModelByTenant(dbTenant, "guest_user", GuestUserSchema);
+    let users = getModelByTenant(dbTenant, "guest_users", GuestUserSchema);

13-32: Well-structured schema with appropriate indexes

The schema definition is well-structured with appropriate field types and validation. Good job adding indexes to guest_id and lastActive fields - this will improve query performance for operations that filter or sort by these fields. The use of the timestamps option is also excellent for automatically tracking document creation and update times.

src/auth-service/routes/v2/guests.routes.js (5)

6-9: Good use of common validator middleware

Excellent job using the common validator middleware. Importing the headers middleware from a common location ensures consistent CORS handling across routes.


11-16: Enhance Security on Guest Creation Endpoint

The guest creation endpoint (located at src/auth-service/routes/v2/guests.routes.js, lines 11–16) currently lacks tenant permission validation and does not include the authentication middlewares (setJWTAuth and authJWT) found in other endpoints. If allowing unauthenticated guest registration is intentional, please ensure that you mitigate potential abuse by:

  • Implementing Rate Limiting: Apply IP-based limits (e.g., 3,600 requests/hour per IP), and consider layered strategies such as allowing a few requests per minute before escalating to CAPTCHA or temporary blocks. This helps manage request volume and discourages automated abuse.
  • Adding Tenant Verification: Validate tenant details during guest creation to ensure that only authorized tenants can register.
  • Consider Managed Challenges: Introducing mechanisms like CAPTCHA for repeated attempts can add an extra layer of security.

These adjustments align with industry best practices for handling unauthenticated user registration while protecting against abuse.


24-31: Enhance Access Control for Guest User Listing

While tenant-based filtering is implemented in the guest user controller, there is no evidence of role-based permission checks. In addition to the tenant filter, please ensure that the guest user listing endpoint enforces restrictions based on the authenticated user's permissions or roles to prevent unauthorized access.

Recommendations:

  • Confirm that role-based access control is applied either in the controller or via dedicated middleware.
  • Consider adding explicit permission checks before invoking guestUserUtil.list.

17-23: Well-structured route handlers with consistent middleware

The route handlers for converting, updating, deleting, and retrieving guest users are well-structured with appropriate HTTP methods, route paths, and middleware chains. Great job applying JWT authentication middleware consistently across these protected endpoints.

Also applies to: 32-55


1-5: Comprehensive import of required dependencies

Good job importing all the necessary dependencies for the router. The imports are well-organized and include the controller, validators, authentication middleware, and common validators.

@Baalmart Baalmart merged commit ef828b9 into staging Mar 4, 2025
50 of 52 checks passed
@Baalmart Baalmart deleted the guest-user-management branch March 4, 2025 11:17
@Baalmart Baalmart mentioned this pull request Mar 4, 2025
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant